package keter.ksf.main;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.*;
import com.jfinal.kit.PropKit;
import keter.framework.util.IOUtil;
import keter.ksf.model.Drink;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

/**
 * Created by gu on 2017/3/1.
 */
public class KsfAppExecutor {

    private static final Logger logger = LoggerFactory.getLogger(KsfAppExecutor.class);

    private static KsfApp app;
    private static int thread;

    static ListeningExecutorService  pool;
    static Map<String,XSSFWorkbook> templateMap = Maps.newConcurrentMap();

    //创建临时目录
    private static String tmpDir;

    public static void init(KsfApp app){
        KsfAppExecutor.app = app;
        tmpDir = StringUtils.substringBeforeLast(PropKit.get("resultFile"),".")+"/";
        IOUtil.ensureExists(tmpDir);
        thread = PropKit.getInt("thread");
    }

    public  static void execute(File[] files , int thread){
        pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(thread));
        List<ListenableFuture<String>> futures = Lists.newArrayList();
        for (File f : files) {
            ListenableFuture<String> future = pool.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Drink drink = app.getDrinkFromFile(f);
//                    logger.info("准备执行:{}",drink.getFileName());
                    XSSFWorkbook template = new XSSFWorkbook(new FileInputStream(new File(PropKit.get("templateFile"))));
                    app.makeResult(drink,template);
                    templateMap.put(drink.getFileName(),template);
                    return drink.getFileName();
                }
            });
            futures.add(future);
        }
        execFutures(futures);
    }

    public static void execFutures(List<ListenableFuture<String>> futures) {
        for (ListenableFuture<String> future : futures) {
            Futures.addCallback(future, new FutureCallback<String>(){
                @Override
                public void onSuccess(String  result) {
                    try {
                        FileOutputStream fileOut = new FileOutputStream(tmpDir+result+".xlsx");
                        KsfApp.writeFile(fileOut,templateMap.get(result));
                        logger.info("文件{}写入完成！",tmpDir+result+".xlsx");
                    } catch (IOException e) {
                        logger.error("文件写入失败!",e);
                    }
                }

                @Override
                public void onFailure(Throwable t) {
                    logger.error("执行失败",t);
                }
            });
        }
        pool.shutdown();
    }

    //TODO:合并文件
    private void mergeToTemplate(XSSFWorkbook template, XSSFWorkbook workbook){
        for (int i = 1; i < 12; i++) {
            XSSFSheet st = template.getSheetAt(i);
//            st.
        }
    }

    //TODO:合并文件
    private List<XSSFWorkbook> getFilesFromTmp() throws IOException {
        File[] files = IOUtil.getFilesInCurrentPath(tmpDir);
        List<XSSFWorkbook> wbList = Lists.newArrayList();
        for (File f : files) {
            XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(f));
            wbList.add(wb);
        }
        return wbList;
    }

    public static void bankai() throws IOException {
        KsfApp app = new KsfApp();
        KsfAppExecutor.init(app);
        File[] files = IOUtil.getFilesInCurrentPath(PropKit.get("inputFolder"));
        if(thread==1) {
            app.bankai();
            return;
        }
        execute(files, thread);
    }

    public static void main(String[] args) throws IOException {
            KsfAppExecutor.bankai();
    }
}